namespace ConcurrentBoo

import System.Threading

interface IChannel:
	def Put(value)
	def Take() as object
	def TryTake(millisecondsTimeout as int, ref value) as bool

class Channel(IChannel):
"""
A channel for thread communication.

There's no guarantee about the order in which values are taken.
"""
	private _head as Node
	
	def Take():
		value as object
		assert TryTake(Timeout.Infinite, value)
		return value
	
	[lock]
	[Boo.Lang.Useful.Attributes.NoTrace]
	def TryTake(millisecondsTimeout as int, ref value):
		while _head is null:
			if not Monitor.Wait(self, millisecondsTimeout):
				return false
		value = _head.Value
		Remove()
		return true
		
	[lock]
	def Put(value):
		Add(value)
		if _head.Next is null:
			Monitor.Pulse(self)
			
	private def Add(value):
		_head = Node(Value: value, Next: _head)
			
	private def Remove():
		_head = _head.Next
			
	private class Node:
		public Value as object
		public Next as Node
		
